home *** CD-ROM | disk | FTP | other *** search
/ SuperHack / SuperHack CD.bin / CODING / GRAPHICS / PHONGSRC.ZIP / MATHUNIT.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1996-01-07  |  5.3 KB  |  178 lines

  1. {   _______________________________________________________________________
  2.   /                                                                         \
  3.  |  This unit provides most of the math. VectorSub, VectorCross, VectorNorm, |
  4.  |  and Calc_Normals where done by cono, so thanx for the help..             |
  5.   \ _______________________________________________________________________ /
  6. }
  7. Unit MathUnit;
  8.  
  9. Interface
  10.  
  11. Uses VarUnit;
  12.  
  13. procedure VectorSub(var a:vect3; b,c : vect3);
  14. procedure VectorCross(var a:vect3; b,c : vect3);
  15. procedure VectorNorm(var a:vect4; b : vect3);
  16. procedure Calc_Normals;
  17. procedure calcpolyZ;
  18. procedure Sort_Polyz;
  19. Procedure Rotate_Vertices;
  20. Procedure Rotate_Normals;
  21.  
  22. Implementation
  23.  
  24. procedure VectorSub(var a:vect3; b,c : vect3);
  25. begin
  26.   a.x := b.x - c.x;
  27.   a.y := b.y - c.y;
  28.   a.z := b.z - c.z;
  29. end;
  30.  
  31. procedure VectorCross(var a:vect3; b,c : vect3);
  32. begin
  33.   a.x := b.y * c.z - b.z * c.y;
  34.   a.y := b.z * c.x - b.x * c.z;
  35.   a.z := b.x * c.y - b.y * c.x;
  36. end;
  37.  
  38. procedure VectorNorm(var a:vect4; b : vect3);
  39. var vtemp : real;
  40. begin
  41.   Vtemp := sqrt( b.x * b.x + b.y * b.y + b.z * b.z);
  42.   a.x := b.x / Vtemp;
  43.   a.y := b.y / Vtemp;
  44.   a.z := b.z / Vtemp;
  45. end;
  46.  
  47. procedure Calc_Normals;
  48. var v1,v2,v3 : vect3;
  49.     vn       : vect4;
  50.     i,j,s    : integer;
  51.     vc       : byte;
  52.     cnt      : longint;
  53.  
  54. begin
  55.   for i := 0 to vert do
  56.     begin
  57.       vertices[i].x := vertices[i].x div 4;
  58.       vertices[i].y := vertices[i].y div 4;
  59.       vertices[i].z := vertices[i].z div 4;
  60.     end;
  61.   for i := 0 to faces do
  62.     begin
  63.       VectorSub(V1, vertices[face[i,1]], vertices[face[i,0]]);
  64.       VectorSub(V2, vertices[face[i,2]], vertices[face[i,0]]);
  65.       VectorCross(V3,v1,v2);
  66.       VectorNorm(vn,v3);
  67.       normals[i] := vn;
  68.     end;
  69.   for j := 0 to faces do
  70.     begin
  71.       for vc := 0 to 2 do
  72.         begin
  73.           cnt := 0;
  74.           for i := 0 to faces do
  75.             begin
  76.               if (face[i][0] = face[j][vc]) or
  77.                  (face[i][1] = face[j][vc]) or
  78.                  (face[i][2] = face[j][vc]) then
  79.                 begin
  80.                   vnormals[j].vn[vc].x := vnormals[j].vn[vc].x + round(normals[i].x*256);
  81.                   vnormals[j].vn[vc].y := vnormals[j].vn[vc].y + round(normals[i].y*256);
  82.                   vnormals[j].vn[vc].z := vnormals[j].vn[vc].z + round(normals[i].z*256);
  83.                   inc(cnt);
  84.                 end;
  85.             end;
  86.           vnormals[j].vn[vc].cnt := cnt;
  87.         end;
  88.     end;
  89.   for j := 0 to faces do
  90.     for vc := 0 to 2 do
  91.       begin
  92.         vnormals[j].vn[vc].x := vnormals[j].vn[vc].x*128;
  93.         vnormals[j].vn[vc].y := vnormals[j].vn[vc].y*128;
  94.         vnormals[j].vn[vc].z := vnormals[j].vn[vc].z*128;
  95.       end;
  96. end;
  97.  
  98. procedure calcpolyZ;
  99. var i : integer;
  100. begin
  101.   for i := 0 to faces do polyz[i] := (z[face[i,0]]+z[face[i,1]]+z[face[i,2]]) div 3;
  102. end;
  103.  
  104. procedure Sort_Polyz;
  105.   procedure sort(l,r:integer);
  106.   var i,j,x,y:integer;
  107.   begin
  108.     i:=l; j:=r; x:=Polyz[(l+r) div 2];
  109.     repeat
  110.       while PolyZ[i]<x do inc(i);
  111.       while x<PolyZ[j] do dec(j);
  112.       if i<=j then
  113.         begin
  114.           y:=PolyZ[i];
  115.           PolyZ[i]:=PolyZ[j];
  116.           PolyZ[j]:=y;
  117.  
  118.           y:=sortedz[i];
  119.           sortedz[i]:=sortedz[j];
  120.           sortedz[j]:=y;
  121.  
  122.           inc(i);
  123.           dec(j);
  124.         end;
  125.     until i>j;
  126.     if l<j then sort(l,j);
  127.     if i<r then sort(i,r);
  128.   end;
  129. begin
  130.   calcpolyz;
  131.   for i := 0 to faces do sortedz[i] := i;
  132.   sort(0,faces);
  133. end;
  134.  
  135. Procedure Rotate_Normals;
  136. Var Tx,Ty,Tz,Sx,Sy,Sz : Longint;
  137. Begin
  138.  for i := 0 to faces do
  139.     for j := 0 to 2 do begin
  140.       TX := (CosTab[Ycnt] * vnormals[i].vn[j].x - SinTab[Ycnt] * vnormals[i].vn[j].z) div 256;
  141.       TZ := (SinTab[Ycnt] * vnormals[i].vn[j].x + CosTab[Ycnt] * vnormals[i].vn[j].z) div 256;
  142.       SX := (CosTab[Zcnt] * TX + SinTab[Zcnt] * vnormals[i].vn[j].y) div 256;
  143.       TY := (CosTab[Zcnt] * vnormals[i].vn[j].y - SinTab[Zcnt] * TX) div 256;
  144.       SZ := (CosTab[Xcnt] * TZ - SinTab[Xcnt] * TY) div 256;
  145.       SY := (SinTab[Xcnt] * TZ + CosTab[Xcnt] * TY) div 256;
  146.       vns[i].vn[j].x := SX;
  147.       vns[i].vn[j].y := SY;
  148.       vns[i].vn[j].z := SZ;
  149.       if sz < 256*256 then FShow[i] := true else FShow[i] := false;
  150.     end;
  151.     for i := 0 to faces do if FShow[i] then
  152.       for j := 0 to 2 do begin
  153.         vns[i].vn[j].x := vns[i].vn[j].x div vnormals[i].vn[j].cnt;
  154.         vns[i].vn[j].y := vns[i].vn[j].y div vnormals[i].vn[j].cnt;
  155.         vns[i].vn[j].xt := vns[i].vn[j].x div 256+127;
  156.         vns[i].vn[j].yt := vns[i].vn[j].y div 256+127;
  157.       end;
  158. end;
  159.  
  160. Procedure Rotate_Vertices;
  161. Var Tx,Ty,Tz  : Longint;
  162.     Sx,Sy,Sz  : Longint;
  163. Begin
  164.   for i := 0 to vert do begin
  165.     Tx := (CosTab[Ycnt] * vertices[i].x - SinTab[Ycnt] * vertices[i].z) DIV 256;
  166.     Tz := (SinTab[Ycnt] * vertices[i].x + CosTab[Ycnt] * vertices[i].z) DIV 256;
  167.     Sx := (CosTab[Zcnt] * Tx + SinTab[Zcnt] * vertices[i].y) DIV 256;
  168.     Ty := (CosTab[Zcnt] * vertices[i].y - SinTab[Zcnt] * Tx) DIV 256;
  169.     Sz := (CosTab[Xcnt] * Tz - SinTab[Xcnt] * Ty) DIV 256;
  170.     Sy := (SinTab[Xcnt] * Tz + CosTab[Xcnt] * Ty) DIV 256;
  171.     X[i] := (256 * Sx div (Sz - Zpos) + Xpos);
  172.     Y[i] := (256 * Sy div (Sz - Zpos) + Ypos);
  173.     Z[i] := SZ;
  174.   end;
  175. end;
  176.  
  177. begin
  178. end.